package com.zdxlz.desensitize.demo;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.ResponseEntity;
//
//import javax.annotation.PostConstruct;
//import javax.servlet.http.HttpServletRequest;
//import java.util.*;
//import java.util.concurrent.TimeUnit;
//
///**
// * 调用远程接口获取规则,附带缓存
// * 缓存失效清除对应key即可
// * @author 宋杨
// * @email s2295938761@163.com
// * @phone 15216839375
// * @date 2023/6/6
// */
//@Slf4j
//public class RemoteWithCacheDesensitizeService implements IDesensitizeService {
//    private final String appId;
//    private final String appSecret;
//    private final RedisUtil redisUtil;
//    private final RestComponent restComponent;
//    /**
//     * KEY的前缀
//     */
//    private final String keyPrefix;
//    private final String url;
//    private final String tokenHeader;
//    /**
//     * 过期时间，单位秒,-1代表永不失效
//     */
//    private final Long expireTime;
//    /**
//     * 如果一个类型有多条规则（常见于一个用户有多个角色），保留规则
//     * 1-保留最后创建的；2-保留序号最大的；3-混合模式；其它-不处理
//     */
//    private final Integer multiHandler;
//
//    public RemoteWithCacheDesensitizeService(String appId, String appSecret,
//                                             RedisUtil redisUtil, RestComponent restComponent, String keyPrefix,
//                                             String url, String tokenHeader,
//                                             Long expireTime, Integer multiHandler) {
//        this.appId = appId;
//        this.appSecret = appSecret;
//        this.redisUtil = redisUtil;
//        this.restComponent = restComponent;
//        this.keyPrefix = keyPrefix;
//        this.url = url;
//        this.tokenHeader = tokenHeader;
//        this.expireTime = null == expireTime?3600L:expireTime;
//        this.multiHandler = null == multiHandler?0:multiHandler;
//    }
//
//    /**
//     * 服务启动时将所有角色规则存入redis
//     * @throws Exception 出现异常应该直接抛出终止程序启动，避免后续invoke时出现更多错误
//     */
//    @PostConstruct
//    private void initAllRules() throws Exception {
//        // TODO 获取所有角色对应的规则，存入redis
//        String getAllRulesUrl = url + "/desensitize/getAllByApp";
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("appId", appId);
//        jsonObject.put("appSecret", appSecret);
//        ResponseEntity<JSONObject> response = restComponent.postNative(getAllRulesUrl, null, jsonObject);
//        Map<String, Object> map = null;
//        if (200 == response.getStatusCodeValue()) {
//            JSONObject body = response.getBody();
//            if (null != body) {
//                map = body.getObject("data", Map.class);
//            }
//        }
//        for (Map.Entry<String, Object> entry: map.entrySet()) {
//            String key = keyPrefix+entry.getKey();
//            if (expireTime == -1) {
//                redisUtil.set(key, entry.getValue());
//            }else {
//                redisUtil.set(key, entry.getValue(), expireTime, TimeUnit.SECONDS);
//            }
//        }
//        log.info("所有角色规则已存入redis,{}",map);
//        String getAllRulesUrl2 = url + "/desensitize2/getAllByApp";
//        response = restComponent.postNative(getAllRulesUrl2, null, jsonObject);
//        if (200 == response.getStatusCodeValue()) {
//            JSONObject body = response.getBody();
//            if (null != body) {
//                map = body.getObject("data", Map.class);
//            }
//        }
//        for (Map.Entry<String, Object> entry: map.entrySet()) {
//            String key = keyPrefix+"s:"+entry.getKey();
//            if (expireTime == -1) {
//                redisUtil.set(key, entry.getValue());
//            }else {
//                redisUtil.set(key, entry.getValue(), expireTime, TimeUnit.SECONDS);
//            }
//        }
//        log.info("所有角色规则2已存入redis,{}",map);
//    }
//
//    // TODO FIXMI TEST
//    @Override
//    public List<String> getRoles(HttpServletRequest request) {
//        String header = request.getHeader(tokenHeader);
//        if ("test".equals(header)) {
//            ArrayList<String> objects = new ArrayList<>();
//            objects.add("test1");
//            objects.add("test2");
//            return objects;
//        }
//        return null;
//    }
//
//    /**
//     * 获取当前查询用户脱敏规则,如果同字段有多个规则，保留一个
//     * 建议把角色id放在redis中
//     *
//     * @param rolesByToken
//     */
//    @Override
//    public List<DesensitizeRule> getRules(List<String> rolesByToken) {
//        String getRulesUrl = url+"/desensitize/getByRole";
//        if (null == rolesByToken) {
//            return null;
//        }
//        List<Map> result = new ArrayList<>();
//
//        for (String roleId: rolesByToken) {
//            String key = keyPrefix+roleId;
//            if(redisUtil.exists(key)) {
//                result.addAll((List) redisUtil.get(key));
//                continue;
//            }
//            List<Map> temp = new ArrayList<>();
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.put("appId", appId);
//            jsonObject.put("roleId", roleId);
//            jsonObject.put("appSecret",appSecret);
//            try {
//                ResponseEntity<JSONObject> response = restComponent.postNative(getRulesUrl, null, jsonObject);
//                if (200 == response.getStatusCodeValue()) {
//                    JSONObject body = response.getBody();
//                    if (null != body) {
//                        List list = body.getObject("data", List.class);
//                        if (null != list &&  !list.isEmpty()) {
//                            for(Object obj: list) {
//                                Map jsonMap = null;
//                                try {
//                                    jsonMap = new JSONObject((Map) obj);
//                                }catch (Exception e) {
//                                    e.printStackTrace();
//                                }
//                                if (null == jsonMap) {
//                                    continue;
//                                }
//                                temp.add(jsonMap);
//                            }
//                        }
//                    }
//                    if (expireTime == -1) {
//                        redisUtil.set(key, temp);
//                    }else {
//                        redisUtil.set(key, temp, expireTime, TimeUnit.SECONDS);
//                    }
//                    result.addAll(temp);
//                }
//            }catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//
//        List<DesensitizeRule> ruleList = new ArrayList<>();
//        for (Map map: result) {
//            ruleList.add(JSON.parseObject(JSON.toJSONString(map), DesensitizeRule.class));
//        }
//        List<DesensitizeRule> desensitizeRules;
//        if ( 1 == multiHandler) {
//            desensitizeRules = keepLastCreate(ruleList);
//        }else if (2 == multiHandler) {
//            desensitizeRules = keepMaxSort(ruleList);
//        }else if (3 == multiHandler) {
//            desensitizeRules = keepLastMix(ruleList);
//        }else {
//            return ruleList;
//        }
//        return desensitizeRules;
//    }
//
//    @Override
//    public List<DesensitizeRuleDto> getRuleDtos(List<String> rolesByToken,String requestURI) {
//        String getRulesUrl = url+"/desensitize2/getByRoleAndUri";
//        if (null == rolesByToken) {
//            return null;
//        }
//        List<Map> result = new ArrayList<>();
//
//        for (String roleId: rolesByToken) {
//            String key = keyPrefix+"s:"+KeyUtil.generateKey(roleId,requestURI);
//            if(redisUtil.exists(key)) {
//                result.addAll((List) redisUtil.get(key));
//                continue;
//            }
//            List<Map> temp = new ArrayList<>();
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.put("appId", appId);
//            jsonObject.put("roleId", roleId);
//            jsonObject.put("uri",requestURI);
//            jsonObject.put("appSecret",appSecret);
//            try {
//                ResponseEntity<JSONObject> response = restComponent.postNative(getRulesUrl, null, jsonObject);
//                if (200 == response.getStatusCodeValue()) {
//                    JSONObject body = response.getBody();
//                    if (null != body) {
//                        List list = body.getObject("data", List.class);
//                        if (null != list &&  !list.isEmpty()) {
//                            for(Object obj: list) {
//                                Map jsonMap = null;
//                                try {
//                                    jsonMap = new JSONObject((Map) obj);
//                                }catch (Exception e) {
//                                    e.printStackTrace();
//                                }
//                                if (null == jsonMap) {
//                                    continue;
//                                }
//                                temp.add(jsonMap);
//                            }
//                        }
//                    }
//                    if (expireTime == -1) {
//                        redisUtil.set(key, temp);
//                    }else {
//                        redisUtil.set(key, temp, expireTime, TimeUnit.SECONDS);
//                    }
//                    result.addAll(temp);
//                }
//            }catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//
//        List<DesensitizeRuleDto> ruleList = new ArrayList<>();
//        for (Map map: result) {
//            ruleList.add(JSON.parseObject(JSON.toJSONString(map), DesensitizeRuleDto.class));
//        }
//        return keepLastMixDto(ruleList);
//    }
//
//    /**
//     * 如果一个类型有多条规则，保留最后创建的
//     */
//    private List<DesensitizeRule> keepLastCreate(List<DesensitizeRule> origin) {
//        if (null == origin || origin.isEmpty()) {
//            return origin;
//        }
//
//        Map<ColumnType, DesensitizeRule> map = new EnumMap<>(ColumnType.class);
//        for(DesensitizeRule rule: origin) {
//            ColumnType column = rule.getColumn();
//            if(map.containsKey(column)) {
//                DesensitizeRule rule1 = map.get(column);
//                if (null == rule1.getCreateTime()) {
//                    if (null != rule.getCreateTime()) {
//                        map.put(column, rule);
//                    }
//                }else {
//                    if (null != rule.getCreateTime() && (rule1.getCreateTime().before(rule.getCreateTime()))) {
//                        map.put(column, rule);
//                    }
//                }
//            }else {
//                map.put(column, rule);
//            }
//        }
//        return new ArrayList<>(map.values());
//    }
//
//    /**
//     * 如果一个类型有多条规则，保留序号最大的
//     */
//    private List<DesensitizeRule> keepMaxSort(List<DesensitizeRule> origin) {
//        if (null == origin || origin.isEmpty()) {
//            return origin;
//        }
//
//        Map<ColumnType , DesensitizeRule> map = new EnumMap<>(ColumnType.class);
//        for(DesensitizeRule rule: origin) {
//            ColumnType column = rule.getColumn();
//            if(map.containsKey(column)) {
//                DesensitizeRule rule1 = map.get(column);
//                if (null == rule1.getSort()) {
//                    if (null != rule.getSort()) {
//                        map.put(column, rule);
//                    }
//                }else {
//                    if (null != rule.getSort() && (rule1.getSort()<rule.getSort())) {
//                        map.put(column, rule);
//                    }
//                }
//            }else {
//                map.put(column, rule);
//            }
//        }
//        return new ArrayList<>(map.values());
//    }
//
//    private List<DesensitizeRule> keepLastMix(List<DesensitizeRule> origin) {
//        if (null == origin || origin.isEmpty()) {
//            return origin;
//        }
//
//        Map<ColumnType, DesensitizeRule> map = new EnumMap<>(ColumnType.class);
//        for(DesensitizeRule rule: origin) {
//            ColumnType column = rule.getColumn();
//            if(map.containsKey(column)) {
//                DesensitizeRule rule1 = map.get(column);
//                if (null == rule1.getSort()) {
//                    if (null != rule.getSort()) {
//                        map.put(column, rule);
//                    }else {
//                        if (null == rule1.getCreateTime()) {
//                            if (null != rule.getCreateTime()) {
//                                map.put(column, rule);
//                            }
//                        }else {
//                            if (null != rule.getCreateTime() && (rule1.getCreateTime().before(rule.getCreateTime()))) {
//                                map.put(column, rule);
//                            }
//                        }
//                    }
//                }else {
//                    if (null != rule.getSort()) {
//                        if (rule1.getSort()<rule.getSort()) {
//                            map.put(column, rule);
//                        }else if (rule1.getSort().equals(rule.getSort())) {
//                            if (null == rule1.getCreateTime()) {
//                                if (null != rule.getCreateTime()) {
//                                    map.put(column, rule);
//                                }
//                            }else {
//                                if (null != rule.getCreateTime() && (rule1.getCreateTime().before(rule.getCreateTime()))) {
//                                    map.put(column, rule);
//                                }
//                            }
//                        }
//                    }
//                }
//            }else {
//                map.put(column, rule);
//            }
//        }
//        return new ArrayList<>(map.values());
//    }
//
//    private List<DesensitizeRuleDto> keepLastMixDto(List<DesensitizeRuleDto> origin) {
//        if (null == origin || origin.isEmpty()) {
//            return origin;
//        }
//
//        Map<String, DesensitizeRuleDto> map = new HashMap<>();
//        for(DesensitizeRuleDto rule: origin) {
//            String column = rule.getColumn();
//            if(map.containsKey(column)) {
//                DesensitizeRuleDto rule1 = map.get(column);
//                if (null == rule1.getSort()) {
//                    if (null != rule.getSort()) {
//                        map.put(column, rule);
//                    }else {
//                        if (null == rule1.getCreateTime()) {
//                            if (null != rule.getCreateTime()) {
//                                map.put(column, rule);
//                            }
//                        }else {
//                            if (null != rule.getCreateTime() && (rule1.getCreateTime().before(rule.getCreateTime()))) {
//                                map.put(column, rule);
//                            }
//                        }
//                    }
//                }else {
//                    if (null != rule.getSort()) {
//                        if (rule1.getSort()<rule.getSort()) {
//                            map.put(column, rule);
//                        }else if (rule1.getSort().equals(rule.getSort())) {
//                            if (null == rule1.getCreateTime()) {
//                                if (null != rule.getCreateTime()) {
//                                    map.put(column, rule);
//                                }
//                            }else {
//                                if (null != rule.getCreateTime() && (rule1.getCreateTime().before(rule.getCreateTime()))) {
//                                    map.put(column, rule);
//                                }
//                            }
//                        }
//                    }
//                }
//            }else {
//                map.put(column, rule);
//            }
//        }
//        return new ArrayList<>(map.values());
//    }
//}
